package com.gitee.wsl.ext.string

import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min

/**
 * 循环位移指定位置的字符串为指定距离<br></br>
 * 当moveLength大于0向右位移，小于0向左位移，0不位移<br></br>
 * 当moveLength大于字符串长度时采取循环位移策略，即位移到头后从头（尾）位移，例如长度为10，位移13则表示位移3
 *
 * @param str          字符串
 * @param startInclude 起始位置（包括）
 * @param endExclude   结束位置（不包括）
 * @param moveLength   移动距离，负数表示左移，正数为右移
 * @return 位移后的字符串
 * @since 4.0.7
 */
fun CharSequence.move(startInclude: Int, endExclude: Int, moveLength: Int): String {
    var moveLength = moveLength
    if (isEmpty()) {
        return toString()
    }
    val str = this
    val len = str.length
    if (abs(moveLength) > len) {
        // 循环位移，当越界时循环
        moveLength = moveLength % len
    }
    val strBuilder= StringBuilder(len)
    if (moveLength > 0) {
        val endAfterMove = min(endExclude + moveLength, str.length)
        strBuilder.append(str.subSequence(0, startInclude)) //
            .append(str.subSequence(endExclude, endAfterMove)) //
            .append(str.subSequence(startInclude, endExclude)) //
            .append(str.subSequence(endAfterMove, str.length))
    } else if (moveLength < 0) {
        val startAfterMove = max(startInclude + moveLength, 0)
        strBuilder.append(str.subSequence(0, startAfterMove)) //
            .append(str.subSequence(startInclude, endExclude)) //
            .append(str.subSequence(startAfterMove, startInclude)) //
            .append(str.subSequence(endExclude, str.length))
    } else {
        return str.toString()
    }
    return strBuilder.toString()
}
